home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1995 #5 & #6
/
Amiga Plus CD - 1995 - No. 5 and 6.iso
/
pd
/
daten
/
astrolog
/
src
/
getkey.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-11
|
6KB
|
282 lines
/* -*- C -*-
* GETKEY.C
*
* (c)Copyright 1990 by Tobias Ferber, All Rights Reserved.
*/
/* $VER: $Id: getkey.c,v 1.2 1995/07/02 22:21:44 tf Exp $ */
#include <stdio.h>
#include "getkey.h"
/* Note: Turbo C Version 1.0 can *NOT* read from non-buffered streams */
#if defined(__TURBOC__)
#undef getkey
#include <conio.h>
int getkey(void) { return getch(); }
#elif defined(GNUDOS)
int getkey(void)
/* read from a non-buffered, binary opened console stream */
{
FILE *con; /* the console stream */
int key;
/* you *MUST* open the console in binary mode for DJGPP
* in order to really get a non-buffered stream via setvbuf()! */
if( con= fopen(CONSOLENAME,"rb") )
{
setvbuf(con,0L,_IONBF,0L); /* better than setbuf(con,0L); ? */
if(ferror(con))
clearerr(con);
fflush(con);
key= (int)fgetc(con);
fclose(con);
}
else key= stdin ? (int)fgetc(stdin) : 0;
return key;
}
#elif defined(__MSDOS__)
#include <dos.h>
/*
* The following stuff is implemented in the c.lib of DJGPP and is
* Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
*
* .globl _getkey
* _getkey:
* pushl %ebx
* pushl %esi
* pushl %edi
* movb $0,%ah
* int $0x16
* cmpb $0,%al
* jnz L1
* movb %ah,%al
* movb $1,%ah
* jmp L2
* L1:
* movb $0,%ah
* L2:
* andl $0xffff,%eax
* popl %edi
* popl %esi
* popl %ebx
* ret
*/
int getkey(void)
/* returns the keycode of the last pressed key using BIOS */
{
union REGS regs; /* defined in <dos.h> */
regs.h.ah= 0x10; /* get MF-II keycode function # */
int86(0x16,®s,®s); /* int 16h -> keycode in regs.x.ax */
return (unsigned short)regs.x.ax;
}
#elif defined(AMIGA)
#include <exec/types.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
/*
* Function - SendPacket written by Phil Lindsay, Carolyn Scheppner, and Andy
* Finkel. This function will send a packet of the given type to the Message
* Port supplied.
*/
typedef struct StandardPacket StandardPacket;
long
SendPacket(pid, action, args, nargs)
struct MsgPort *pid; /* process indentifier ... (handler's message port) */
long action; /* packet type ... (what you want handler to do) */
long *args; /* a pointer to an argument list */
long nargs; /* number of arguments in list */
{
struct MsgPort *replyport;
StandardPacket *packet;
long count, *pargs, res1;
replyport= (struct MsgPort *)CreatePort(NULL, 0L);
if (!replyport)
return(0);
/* Allocate space for a packet, make it public and clear it */
packet = (StandardPacket *)
AllocMem(sizeof(StandardPacket), MEMF_PUBLIC | MEMF_CLEAR);
if (!packet) {
DeletePort(replyport);
return(0);
}
packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
packet->sp_Pkt.dp_Port = replyport;
packet->sp_Pkt.dp_Type = action;
/* copy the args into the packet */
pargs = &(packet->sp_Pkt.dp_Arg1); /* address of first argument */
for (count = 0; count < nargs; count++)
pargs[count] = args[count];
PutMsg(pid, &packet->sp_Msg); /* send packet */
WaitPort(replyport);
GetMsg(replyport);
res1 = packet->sp_Pkt.dp_Res1;
FreeMem(packet, sizeof(StandardPacket));
DeletePort(replyport);
return (res1);
}
int getkey(void)
{
int key= 0; /* the one we're going to return */
BPTR con; /* BCPL pointer to a struct FileHandle */
/* We must use Open() here -- not Input() -- because last may
* be redirected. */
con= Open( CONSOLENAME, MODE_OLDFILE );
if( BADDR(con) && IsInteractive(con) )
{
struct MsgPort *mp;
long arg[1], res;
mp = ((struct FileHandle *)(BADDR(con)))->fh_Type;
arg[0]= -1L; /* make it RAW */
res= SendPacket(mp, ACTION_SCREEN_MODE, arg, 1);
if(res)
{
char buffer[4]; /* just to be sure... */
long actualLength; /* return value */
/* The value returned by Read() is the length of the information
* actually read. So when 'actualLength' is > 0, then it is the
* number of characters read. A value of zero means that the
* end-of-file has been reached. Errors are indicated by a value
* of -1. Note: Read is an unbuffered routine. */
actualLength = Read( con, buffer, (long)sizeof(buffer)-1 );
/* 1 extra (for the bugs) */
if(actualLength > 0)
key= (int)buffer[0];
arg[0]= 0L; /* make it COOKED */
(void)SendPacket(mp, ACTION_SCREEN_MODE, arg, 1);
}
/* Note that we must close 'con' again, whereas Input() must NEVER
* be closed. */
Close(con);
}
if(!key)
key= getchar(); /* just to be sure... */
return key;
}
#elif defined(unix) || defined(__alpha)
#include <curses.h>
int getkey(void)
{
char c;
#ifdef OBSOLETE
/* try /dev/tty. If that doesn't work, use file descriptor 2,
* which in Unix is usually attached to the screen, but also
* usually lets you read from the keyboard. */
int tty= open("/dev/tty", 0);
if(tty < 0)
tty= 2;
{ int result;
do {
result= read(tty, &c, sizeof(char));
} while( result != 1 );
}
if(tty!=2)
close(tty);
#else /* POSIX */
initscr();
savetty();
cbreak();
noecho();
c= getch();
resetty();
endwin();
#endif
return c;
}
#endif /* which machine? */
#ifdef TEST
#include <stdlib.h>
main(int argc, char **argv)
{
int err= 0;
if(argc==2)
{
char *s= argv[1];
do {
char c= getkey();
#ifdef DEBUG
printf("getkey() returned 0x%02x\n",c)
#endif
for(err=0; s[err]!='\0'; err++)
if(c==s[err])
break;
} while(s[err]=='\0');
}
else
{ puts("GETKEY [keys]\n\n"
"GetKey wartet auf eine der Tasten in 'keys' und gibt den\n"
"Index der gedrueckten Taste aus 'keys' im Errorlevel zurueck");
}
#ifdef DEBUG
printf("errorlevel=%d\n",err);
#endif
exit(err);
}
#endif /* TEST */